package com.cyzy.service.impl;

import com.cyzy.dto.ChatMessage;
import com.cyzy.dto.ChatSession;
import com.cyzy.service.ChatSessionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 聊天会话服务实现类
 * 使用Redis存储，替代之前的内存存储
 * @author LIGHT
 */
@Service
public class ChatSessionServiceImpl implements ChatSessionService {
    private static final Logger logger = LoggerFactory.getLogger(ChatSessionServiceImpl.class);
    
    private static final String SESSION_KEY_PREFIX = "chat:session:";
    private static final String SESSION_LIST_KEY = "chat:session:list:";
    private static final String MESSAGE_KEY_PREFIX = "chat:message:";
    private static final long SESSION_EXPIRE_TIME = 60 * 60 * 24 * 30; // 30天过期
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public ChatSession createSession(String userId) {
        ChatSession session = new ChatSession();
        session.setId(UUID.randomUUID().toString());
        session.setUserId(userId);
        session.setTitle("新会话 " + LocalDateTime.now().toString());
        session.setCreateTime(LocalDateTime.now());
        session.setUpdateTime(LocalDateTime.now());
        
        // 保存会话到Redis
        redisTemplate.opsForValue().set(SESSION_KEY_PREFIX + session.getId(), session, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
        
        // 添加到用户会话列表
        String userSessionListKey = SESSION_LIST_KEY + userId;
        redisTemplate.opsForList().rightPush(userSessionListKey, session.getId());
        redisTemplate.expire(userSessionListKey, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
        
        // 初始化消息列表为空列表
        redisTemplate.opsForValue().set(MESSAGE_KEY_PREFIX + session.getId(), new ArrayList<ChatMessage>(), SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
        
        logger.info("创建新会话: {}", session.getId());
        return session;
    }

    @Override
    public ChatSession getSession(String sessionId) {
        ChatSession session = (ChatSession) redisTemplate.opsForValue().get(SESSION_KEY_PREFIX + sessionId);
        if (session != null) {
            List<ChatMessage> messages = getSessionMessages(sessionId);
            session.setMessages(messages);
            return session;
        } else {
            logger.warn("未找到会话: {}", sessionId);
            return null;
        }
    }

    @Override
    public List<ChatSession> getUserSessions(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            logger.warn("获取会话列表时用户ID为空");
            return Collections.emptyList();
        }
        
        String userSessionListKey = SESSION_LIST_KEY + userId;
        List<Object> sessionIds = redisTemplate.opsForList().range(userSessionListKey, 0, -1);
        
        if (sessionIds == null || sessionIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        List<ChatSession> sessions = new ArrayList<>();
        for (Object idObj : sessionIds) {
            String sessionId = idObj.toString();
            ChatSession session = (ChatSession) redisTemplate.opsForValue().get(SESSION_KEY_PREFIX + sessionId);
            if (session != null) {
                sessions.add(session);
            }
        }
        
        // 按更新时间排序
        sessions.sort(Comparator.comparing(ChatSession::getUpdateTime).reversed());
        return sessions;
    }

    @Override
    public ChatMessage addMessage(String sessionId, ChatMessage message) {
        if (sessionId == null || message == null) {
            logger.error("添加消息失败: 会话ID或消息为空");
            throw new IllegalArgumentException("会话ID或消息不能为空");
        }
        
        // 检查会话是否存在
        ChatSession session = (ChatSession) redisTemplate.opsForValue().get(SESSION_KEY_PREFIX + sessionId);
        if (session == null) {
            logger.error("会话不存在: {}", sessionId);
            throw new RuntimeException("会话不存在");
        }
        
        message.setId(UUID.randomUUID().toString());
        message.setSessionId(sessionId);
        if (message.getCreateTime() == null) {
            message.setCreateTime(LocalDateTime.now());
        }
        
        // 获取并更新消息列表
        List<ChatMessage> messages = getSessionMessages(sessionId);
        if (messages == null) {
            messages = new ArrayList<>();
        }
        
        // 添加新消息
        messages.add(message);
        
        // 重新保存消息列表
        redisTemplate.opsForValue().set(MESSAGE_KEY_PREFIX + sessionId, messages, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
        
        // 更新会话时间
        session.setUpdateTime(LocalDateTime.now());
        
        // 如果是第一条消息，更新会话标题
        if (messages.size() == 1 && "user".equals(message.getRole())) {
            String title = message.getContent();
            // 截取前20个字符作为标题
            if (title.length() > 20) {
                title = title.substring(0, 20) + "...";
            }
            session.setTitle(title);
            logger.info("自动更新会话标题: {}", title);
        }
        
        // 保存更新后的会话
        redisTemplate.opsForValue().set(SESSION_KEY_PREFIX + sessionId, session, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
        
        logger.debug("添加消息到会话 {}: {}", sessionId, message.getId());
        return message;
    }

    @Override
    public List<ChatMessage> getSessionMessages(String sessionId) {
        if (sessionId == null) {
            return Collections.emptyList();
        }
        
        List<ChatMessage> messages = (List<ChatMessage>) redisTemplate.opsForValue().get(MESSAGE_KEY_PREFIX + sessionId);
        return messages != null ? messages : Collections.emptyList();
    }

    @Override
    public ChatSession updateSessionTitle(String sessionId, String title) {
        if (sessionId == null || title == null) {
            logger.error("更新会话标题失败: 会话ID或标题为空");
            throw new IllegalArgumentException("会话ID或标题不能为空");
        }
        
        ChatSession session = (ChatSession) redisTemplate.opsForValue().get(SESSION_KEY_PREFIX + sessionId);
        if (session == null) {
            logger.error("会话不存在: {}", sessionId);
            throw new RuntimeException("会话不存在");
        }
        
        session.setTitle(title);
        session.setUpdateTime(LocalDateTime.now());
        
        // 保存更新后的会话
        redisTemplate.opsForValue().set(SESSION_KEY_PREFIX + sessionId, session, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
        
        logger.info("更新会话标题 {}: {}", sessionId, title);
        return session;
    }

    @Override
    public boolean deleteSession(String sessionId) {
        if (sessionId == null) {
            return false;
        }
        
        ChatSession session = (ChatSession) redisTemplate.opsForValue().get(SESSION_KEY_PREFIX + sessionId);
        if (session != null) {
            // 从用户会话列表中移除
            String userSessionListKey = SESSION_LIST_KEY + session.getUserId();
            List<Object> sessionIds = redisTemplate.opsForList().range(userSessionListKey, 0, -1);
            if (sessionIds != null && !sessionIds.isEmpty()) {
                // 创建新的会话ID列表（排除要删除的会话ID）
                List<Object> newSessionIds = sessionIds.stream()
                        .filter(id -> !sessionId.equals(id.toString()))
                        .collect(Collectors.toList());
                
                // 删除旧的列表
                redisTemplate.delete(userSessionListKey);
                
                // 保存新的列表
                if (!newSessionIds.isEmpty()) {
                    redisTemplate.opsForList().rightPushAll(userSessionListKey, newSessionIds);
                    redisTemplate.expire(userSessionListKey, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
                }
            }
            
            // 删除会话和消息
            redisTemplate.delete(SESSION_KEY_PREFIX + sessionId);
            redisTemplate.delete(MESSAGE_KEY_PREFIX + sessionId);
            
            logger.info("删除会话: {}", sessionId);
            return true;
        }
        
        logger.warn("删除会话失败，会话不存在: {}", sessionId);
        return false;
    }
} 